import {usePoetry} from "../ poetry-hooks";
import React, {useState, useEffect, useRef} from "react";
import {removeTone} from "../helpers/tone-helper";
import {StyledTopInput, StyledWord, StyledXing, StyledYin, StyledInputWithTip} from "./word-style";
import {Icon, Position, Tooltip} from "@blueprintjs/core";
import {Intent} from "@blueprintjs/core/lib/cjs/common/intent";
import {IconNames} from "@blueprintjs/icons";
import styled from "styled-components";
import {addError} from "../helpers/storage";
import {splitPhonics} from "../helpers/phonics-helper";
import {KeyCodes} from "../helpers/keyboard";


const StyledCheck = styled(Icon)`
position: absolute;
top: 12px;
right: -10px;
`;

export function Word(props) {
    const {
        showPinyin, showTone, question, goNext, selectedIndex, trainFromError,
        userWeak, addPlayItem,
        keyboard, setNextKey,
        weakTip, threeDaysWeak
    } = usePoetry();
    const {row, column, next} = props;
    const isFirst = question && (row === question.coordinate[0] && column === question.coordinate[1]);
    const [toolTip, setTooltip] = useState({
        tips: '',
        show: false,
    });
    const isFirstWordAndIsName = (column === 0 && next.xing === ':') || /^\d+$/.test(props.yin);
    const [right, setRight] = useState(false);
    const [showWrong, setShowWrong] = useState(false);
    const [isCurrent, setIsCurrent] = useState(false);
    // const isCurrent = question.coordinate[0] === row && question.coordinate[1] === column;
    const ref = useRef();
    const removedToneYin = removeTone(props.yin);

    const updateNextKey = (currentValue, isRight=false, isWrong=false) => {
        if(!keyboard) {
            return;
        }

        if (isRight) {
            setNextKey(KeyCodes.space);
            return;
        }

        if (isWrong) {
            setNextKey(KeyCodes.backspace);
            return;
        }

        if(currentValue !== false) {
            setNextKey(removedToneYin[currentValue.length].charCodeAt(0));
        } else {
            setNextKey(false);
        }
    };


    const onKeyDown = (event) => {
        const isEnglish = true;
        const isEmpty = (event.target.value.trim().length === 0);
        const wantNext = ['Enter', ' ', 'ArrowDown'].includes(event.key);
        const isLeftKey = ['ArrowLeft'].includes(event.key);
        const isNav = isLeftKey || wantNext;
        const isControlKey = (isLeftKey || ['Tab', 'Backspace', 'ArrowRight'].includes(event.key));
        const isAlphabet = isEnglish ? /^[a-zA-Z-'0-9]$/.test(event.key) : /^[a-z]$/.test(event.key);
        const isUpperCase = isEnglish ? false : /^[A-Z]$/.test(event.key);
        const sameWithLastChar = isEnglish ? false : !isEmpty && event.target.value.trim().endsWith(event.key);
        const isLeftEdge = event.target.selectionStart === 0;
        const isLeft = isLeftKey && isLeftEdge;

        if (isNav) {
            const form = event.target.form;
            const index = Array.prototype.indexOf.call(form, event.target);
            const isLastInput = (index === form.elements.length - 1);
            const isRight = event.target.value === removedToneYin;
            console.log(event.target.value, removedToneYin, "isRight")

            // 不正确,不能转到下一个
            if (!isRight && !isLeftKey) {
                event.preventDefault();
                setShowWrong(true);
                return;
            }

            if (!isEmpty && wantNext && !isLastInput) {
                setIsCurrent(false);
                form.elements[index + 1].focus();
            } else {
                if (isLeft && index > 0) {
                    setIsCurrent(false);
                    form.elements[index - 1].focus();
                }
            }

            if (wantNext && isLastInput) {
                const rightLength = document.querySelectorAll('form [icon=tick]').length;
                goNext(rightLength)
            }
        }

        if (!isControlKey && (!isAlphabet || sameWithLastChar)) {
            event.preventDefault();
        }

        if (isUpperCase) {
            setTooltip({
                tips: '请使用小写字母',
                show: true,
            });
        } else {
            if (toolTip.show) {
                setTooltip({
                    tips: '',
                    show: false,
                });
            }
        }
    };

    const checkResult = (event) => {
        const isRight = event.target.value === removedToneYin;
        setRight(isRight);

        let tag = false;
        if (event.type === 'blur') {
            tag = (event.target.value.length > 0) && !isRight;
            setIsCurrent(false);
            updateNextKey(false);
        } else {
            tag = !removedToneYin.startsWith(`${event.target.value}`);
            updateNextKey(event.target.value, isRight, tag);
        }

        setShowWrong(tag);
        if (tag) {
            addPlayItem(props.yin);
            addError(removedToneYin);
        }
    };

    function setCaretPosition(e) {
        setIsCurrent(true);
        const ctrl = e.target;
        const pos = ctrl.value.length;
        setTimeout(() => {
            // Modern browsers
            if (ctrl.setSelectionRange) {
                ctrl.setSelectionRange(pos, pos);
            }
        }, 150);
    }

    function onFocus(e){
        addPlayItem(props.yin);
        setCaretPosition(e);
        if(removedToneYin.length) {
            const ctrl = e.target;
            const pos = ctrl.value.length;
            if(pos === 0) {
                updateNextKey('');
            }
        }
    }

    useEffect(() => {
        if (isFirst && ref.current) {
            ref.current.focus()
        }
    }, [showPinyin, selectedIndex, trainFromError, isFirst, weakTip]);

    const onXingClick = () => {
        if (ref.current) {
            ref.current.focus()
        }
        // addPlayItem(splitPhonics(removedToneYin));
        addPlayItem(props.yin);
    };

    const showResult = true;
    const result = (
        <>
            {right && <StyledCheck icon={IconNames.TICK} iconSize={Icon.SIZE_LARGE} intent={Intent.SUCCESS}/>}
            {showWrong && <StyledCheck icon={IconNames.CROSS} iconSize={Icon.SIZE_LARGE} intent={Intent.DANGER}/>}
        </>
    );

    const InputWithTip = (
        <StyledInputWithTip>
            <Tooltip intent={Intent.WARNING}
                     isOpen={toolTip.show}
                     content={<span>{`${toolTip.tips}`}</span>}
                     position={Position.RIGHT}>
                <StyledTopInput
                    ref={ref}
                    maxlength={8}
                    onKeyDown={onKeyDown}
                    onKeyUp={checkResult}
                    onBlur={checkResult}
                    onFocus={onFocus}
                />
            </Tooltip>
            {showResult && result}
        </StyledInputWithTip>
    );

    const displayYin = showTone ? props.yin : removedToneYin;
    let inErrors = false;
    if (trainFromError) {
        inErrors = !!userWeak[removedToneYin]
    }
    if (weakTip) {
        inErrors = !!threeDaysWeak[removedToneYin]
    }

    return (<StyledWord hasPinyin={showPinyin} isPunctuation={props.yin.length === 0}>
        {(weakTip || showPinyin) && (weakTip || !inErrors) &&
        <StyledYin inErrors={inErrors}>{props.yin.length > 0 ? displayYin : props.yin.length === 0 && props.xing.length !== 0 ? props.xing : ''}</StyledYin>}
        {!weakTip && (!showPinyin || inErrors) && (props.yin.length > 0 && !isFirstWordAndIsName ? InputWithTip : <StyledYin/>)}
        <StyledXing
            isCurrent={isCurrent}
            inErrors={weakTip ? inErrors : false}
            onClick={onXingClick}
        >{props.xing}</StyledXing>
    </StyledWord>)
}
